package org.yak.core.nosql;

import java.io.File;
import java.net.URLDecoder;

import org.apache.log4j.Logger;

import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.Future;

import net.spy.memcached.CASResponse;
import net.spy.memcached.CASValue;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.OperationTimeoutException;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

/**
 *
 * @平台：FAMSUN统一开发平台
 * @文件名称：MemcachedCacheConfig.java
 * @文件描述：Memcached缓存处理器
 * @author xq
 * @日期：2017年11月10日上午9:17:47
 *
 */
public class MemcachedCacheConfig {

	private static Logger logger = Logger.getLogger(MemcachedCacheConfig.class);

    /**
     * 创建xmemcached客户端对像
     */
    private static ApplicationContext context;

    /**
     * memcached客户端
     */
    private static MemcachedClient memcachedClient;

    static {
        try {
        	String memcachedPath = Thread.currentThread().getContextClassLoader().getResource("/memcached.xml").getPath();
        	memcachedPath = URLDecoder.decode(memcachedPath, "UTF-8");
        	logger.error("memcachedPath地址："+memcachedPath);
        	File file = new File(memcachedPath);
        	logger.error("文件："+file.getAbsolutePath());
			if(file.exists()){
	            // 加载memcached配置文件
				logger.error("配置地址："+"file:" + memcachedPath);
				context=new FileSystemXmlApplicationContext("file:" + memcachedPath);
	            // 配置测试渠道memcached地址
	            logger.error("正在配置Memcached服务......");

	            memcachedClient = (MemcachedClient) context.getBean("memcachedClient");

	            //系统重启清空缓存
	            //memcachedClient.flush();
	            //测试memcached是否连接，测试数据生存时间为1分钟
	            update("test_ZH_CN", 0, "test");
	            logger.info(memcachedClient.get("memcachedtest"));
	            logger.info("Memcached服务配置成功!");
			}else{
				logger.error("memcached配置文件不存在，服务无法提供");
			}


        } catch (Exception e) {
            logger.error("获取Memcached配置文件异常", e);
        }
    }

    /**
     * 刷新缓存
     * @方法没描述：
     * @author XQ
     */
    public static void fulshMemcached(){
    	memcachedClient.flush();
    }

    /**
     * Get方法, 转换结果类型并屏蔽异常,仅返回Null.
     */
    public static String get(String key) {
        try {
            return String.valueOf(memcachedClient.get(key)==null?"":memcachedClient.get(key));
        } catch (OperationTimeoutException e) {
            logger.error("Get from memcached server timeout,key is" + key, e);
            return null;
        } catch (RuntimeException e) {
            logger.error("Get from memcached server fail,key is " + key, e);
            return null;
        }
    }

    /**
     * 获取对象
     *
     * @param key
     * @return
     */
    public static Object getObject(String key) {
        if (memcachedClient != null && key != null && key.trim().length() > 0) {
            try {
                return memcachedClient.get(key);
            } catch (OperationTimeoutException e) {
                logger.error("Get from memcached server timeout,key is" + key, e);
                return null;
            } catch (RuntimeException e) {
                logger.error("Get from memcached server fail,key is " + key, e);
                return null;
            }
        }
        return null;
    }

    /**
     *
     * @方法没描述：添加缓存
     * @author xq
     * @param name
     * @param obj
     * @param delay 超时时间单位秒，如果设置用不过期则设置0
     */
    public static void addObject(String name, int delay, Object obj) {
        if (null != memcachedClient.get(name)) {
            // 如果存在先删除再添加
            memcachedClient.delete(name);
        }
        memcachedClient.add(name, delay, obj);
    }

    /**
     * 添加会 覆盖
     */
    public static void update(String name, int delay, Object obj) {
        if (null != memcachedClient.get(name)) {
            // 如果存在则更新
            memcachedClient.replace(name, delay, obj);
        }
        // 如果不存在则添加
        memcachedClient.add(name, delay, obj);
    }

    /**
     * Set方法.
     *
     * @param expiredTime 过期时间 单位秒
     */
    public static Future<Boolean> set(String key, int delay, Object value) {
        Future<Boolean> result = null;
        try {
            result = memcachedClient.set(key, delay, value);
        } catch (Exception ex) {
            logger.error(ex);
        }
        return result;
    }

    /**
     * Delete方法.
     */
    public static boolean delObject(String key) {
    	if (null != memcachedClient.get(key)) {
    		memcachedClient.delete(key);
    		return true;
    	}
    	return false;
    }

    /**
     * flush方法.
     */
    public static Future<Boolean> flush() {
        return memcachedClient.flush();
    }

    /**
     * 配合Check and Set的Get方法,转换结果类型并屏蔽异常.
     */
    @SuppressWarnings("unchecked")
    public <T> CASValue<T> gets(String key) {
        try {
            return (CASValue<T>) memcachedClient.gets(key);
        } catch (RuntimeException e) {
            logger.warn("Get from memcached server fail,key is" + key, e);
            return null;
        }
    }

    /**
     * GetBulk方法, 转换结果类型并屏蔽异常.
     */
    @SuppressWarnings("unchecked")
    public <T> Map<String, T> getBulk(String... keys) {
        try {
            return (Map<String, T>) memcachedClient.getBulk(keys);
        } catch (RuntimeException e) {
            logger.warn("Get from memcached server fail,keys are " + Arrays.toString(keys), e);
            return null;
        }
    }

    /**
     * GetBulk方法, 转换结果类型并屏蔽异常.
     */
    @SuppressWarnings("unchecked")
    public <T> Map<String, T> getBulk(Collection<String> keys) {
        try {
            return (Map<String, T>) memcachedClient.getBulk(keys);
        } catch (RuntimeException e) {
            logger.warn("Get from memcached server fail,keys are " + keys, e);
            return null;
        }
    }

    /**
     * Check and Set方法.
     */
    public CASResponse cas(String key, long casId, Object value) {
        return memcachedClient.cas(key, casId, value);
    }

    /**
     * Incr方法.
     */
    public long incr(String key, int by, long defaultValue) {
        return memcachedClient.incr(key, by, defaultValue);
    }

    /**
     * Decr方法.
     */
    public long decr(String key, int by, long defaultValue) {
        return memcachedClient.decr(key, by, defaultValue);
    }

    /**
     * 异步Incr方法, 不支持默认值, 若key不存在返回-1.
     */
    public Future<Long> asyncIncr(String key, int by) {
        return memcachedClient.asyncIncr(key, by);
    }

    /**
     * 异步Decr方法, 不支持默认值, 若key不存在返回-1.
     */
    public Future<Long> asyncDecr(String key, int by) {
        return memcachedClient.asyncDecr(key, by);
    }

    public void destroy() throws Exception {
        if (memcachedClient != null) {
            memcachedClient.shutdown();
        }
    }

    public static void main(String[] args) {
		//System.out.println(MemcachedCacheConfig.getObject("1407227365968217"));
		memcachedClient.add("test_n", 0, "a");
		while(true){
			try{
				System.out.println(memcachedClient.get("test_n")+String.valueOf(memcachedClient.incr("test_n", 1)));
				Thread.sleep(1000);

			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
}
